/*
1.多个线程的执行顺序是混乱的，与系统内部的线程运行调度机制有关
2.数据共享问题
	a.只读数据是安全的
	b.读写数据会产生同时写入时的冲突
		解决：不同时读，不同时写，不同时读写
*/


#include<iostream>
#include<thread>
#include<vector>
#include <list>

using namespace std;


//全局变量，共享数据
//只读（没有写入数据，最好加上const修饰）
//他是安全的，不需要特殊的处理手段
const vector<int> g_v = { 1,2,3 };


//线程入口函数
void  myprint(int num) {
	//cout << "myprint开始执行了，编号" << num<<endl;
	//cout << "myprint结束执行了，编号" <<num<< endl;
	
	//this_thread是一个命名空间，里面有get_id方法
	cout << "id 为" << this_thread::get_id() << "的线程 打印g_v的值是" << g_v[0] << g_v[1] << g_v[2] << endl;
	return;

}



class A {
public:
	//线程入口，读入消息队列
	//把收到的命令放入一个队列的线程
	void inMsgRecvQueue() {
		for (int i = 0; i < 100000; ++i) {
			cout << "插入元素" << i << endl;
			//假设i就是我们接受的数据
			msgRecvQueue.push_back(i);
		}
	}

	//线程入口，取出消息队列
	void outMsgRecvQueue() {
		for (int i = 0; i < 100000; ++i) {
			if (!msgRecvQueue.empty()) {
				//如果消息不为空
				//从头取出来（从尾插入的，从头取）
				int command = msgRecvQueue.front();
				//释放头指针
				msgRecvQueue.pop_front();
			}
			else {
				//如果为空
				cout << "消息为空" << i<<endl;
			}
		}
		cout << "消息处理结束" << endl;
	}

private:
	//用来存放数据的容器
	//共享数据
	std::list<int> msgRecvQueue;
};


int main(int argc, char* argv[]) {
	////存放线程的容器
	//vector<thread> mythreads;
	////创建10个线程，入口函数统一使用myrpint
	//for (int i = 0; i < 10; i++) {
	//	//创建并开始执行线程
	//	//多个线程的执行顺序是混乱的，与系统内部的线程运行调度机制有关
	//	mythreads.push_back(thread(myprint, i));
	//}

	//for (vector<thread>::iterator iter = mythreads.begin(); iter != mythreads.end(); iter++) {
	//	//等待10个进程全部返回
	//	(*iter).join();
	//}


	//创建线程,第二个参数用引入方式传递，保证一直都是源对象
	//第二个参数表示运行的目标，即第一个参数作为线程在第二个参数对象上运行
	A myobja;
	thread myOutMsgObj(&A::outMsgRecvQueue, &myobja);
	thread myInMsgObj(&A::inMsgRecvQueue, &myobja); 
	myOutMsgObj.join();
	myInMsgObj.join();
	//上述代码会因为读写问题报错
	//引入互斥量，来解决问题



	//最后主线程执行，进程退出
	cout << "Hello" << endl;
	return 0;
}